// Copyright (C) 2025, ZWSOFT Co., LTD.(Guangzhou)
// Licensed under the MIT License. See LICENSE in the project root for license information.

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using TestClient.Domain;

namespace TestClient.ViewModel;
public partial class SurfaceSewTestViewModel : PageViewModelBase
{
    [ObservableProperty]
    private string surface1Id = "";
    [ObservableProperty]
    private string surface2Id = "";
    [ObservableProperty]
    private string isCoincident = "";
    [ObservableProperty]
    private string coincideLineId = "";

    [ObservableProperty]
    private string surfaceList = "";
    [ObservableProperty]
    private string sewResultId = "";

    private List<string> surface_list = [];

    public IAsyncRelayCommand SelectSurface1Command { get; }
    public IAsyncRelayCommand SelectSurface2Command { get; }
    public IAsyncRelayCommand TestSurfaceBoundaryCoincidenceCommand { get; }
    public IAsyncRelayCommand SelectSurfaceListCommand { get; }
    public IAsyncRelayCommand TestSurfaceJoinCommand { get; }
    public IAsyncRelayCommand TestSurfaceJoinOnlyCommand { get; }

    public SurfaceSewTestViewModel(
        VFAdapterWrapper wrapper,
        ISnackNotifyService notifyService) : base(wrapper, notifyService)
    {
        SelectSurface1Command = CreateAsyncRpcCommand(SelectSurface1Async);
        SelectSurface2Command = CreateAsyncRpcCommand(SelectSurface2Async);
        TestSurfaceBoundaryCoincidenceCommand = CreateAsyncRpcCommand(TestSurfaceBoundaryCoincidenceAsync);
        SelectSurfaceListCommand = CreateAsyncRpcCommand(SelectSurfaceListAsync);
        TestSurfaceJoinCommand = CreateAsyncRpcCommand(TestSurfaceJoinAsync);
        TestSurfaceJoinOnlyCommand = CreateAsyncRpcCommand(TestSurfaceJoinOnlyAsync);
    }

    private async Task SelectSurface1Async()
    {
        EnsureConnected();
        Surface1Id = await ViewModelHelpers.SelectEnt(Wrapper, "Surface");
    }

    private async Task SelectSurface2Async()
    {
        EnsureConnected();
        Surface2Id = await ViewModelHelpers.SelectEnt(Wrapper, "Surface");
    }

    private async Task TestSurfaceBoundaryCoincidenceAsync()
    {
        EnsureConnected();

        var (is_coincide, coincide_line) = await Task.Run(() =>
        {
            var result = Wrapper.TestCoincideSurface(Surface1Id, Surface2Id, out var coincideLine);
            return (result, coincideLine);
        });

        IsCoincident = is_coincide switch
        {
            0 => "Not Coincident",
            1 => "Coincident",
            _ => "Error",
        };
        CoincideLineId = coincide_line;
    }

    private async Task SelectSurfaceListAsync()
    {
        EnsureConnected();
        surface_list = await Task.Run(() =>
        {
            return Wrapper.MultiSelect("Surface");
        });
        SurfaceList = string.Join(", ", surface_list);
    }

    private async Task TestSurfaceJoinAsync()
    {
        EnsureConnected();
        SewResultId = await Task.Run(() =>
        {
            return Wrapper.SurfaceJointAndGetBoundary([.. surface_list]);
        });
    }

    private async Task TestSurfaceJoinOnlyAsync()
    {
        EnsureConnected();
        SewResultId = await Task.Run(() =>
        {
            return Wrapper.SurfaceJoint([.. surface_list]);
        });
    }
}
